/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package idea.sfo.viewer.graphics;


import designersfo.Cons.CellInfo.CellFormat;
import idea.sfo.viewer.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.NoSuchElementException;


/**
 * Border style enumeration defined here:
 * https://censuswiki.fenestra.com/bin/view/Main/StyleEnum
 * <p/>
 *
 * @author renke002
 */
public class CellBorder implements Drawable
{

    /**
     * Render the border using the background color; (i.e., the border is
     * present, with its specified thickness, but invisible).
     */
    public final static String BORDER_STYLE_HIDDEN = "hidden";
    /**
     * Do not render the border at all.
     */
    public final static String BORDER_STYLE_NONE = "none";
    /**
     * Render the border as a solid line.
     */
    public final static String BORDER_STYLE_SOLID = "solid";
    /**
     * Render the border using the parent (i.e., containing) block's border
     * style.
     */
    public final static String BORDER_STYLE_USE_PARENT = "use-parent";
    /**
     * @deprecated
     */
    @Deprecated
    private int borderThickness = 1;
    /**
     * Mapping between position (TOP, RIGHT, BOTTOM, LEFT) and the borders
     * around this cell.
     */
    private HashMap< Integer , Border> borders = new HashMap<>();
    /**
     * List containing all the borders around this cell.Border
     * <p/>
     * @deprecated
     */
    @Deprecated
    private ArrayList<Rectangle> cellBorders;
    /**
     * Representation of the cell in space as a rectangle with coordinates and
     * size.
     */
    private Rectangle cell;
    /*
     **********THESE-VARIABLES-ARE-ATTRIBUTES-OF-THE-CELL-INFO-ELEMENT**********
     */
    // 
    /**
     * Attribute from <gids-designer:cell-info> - joined-cell-count-h <p>
     * Integer / required; indicates that this cell is a member of a group of
     * joined-cell-count-h cells joined in the horizontal direction
     * <p/>
     * @deprecated
     */
    @Deprecated
    private int joinedHorizCellsCount;
    /**
     * Attribute from <gids-designer:cell-info> - joined-cell-count-v <p>
     * Integer / required; indicates that this cell is at the
     * joined-cell-index-h'th (ZERO-based) horizontal position in the group of
     * which it is a member
     * <p/>
     * @deprecated
     */
    @Deprecated
    private int joinedHorizCellsIndex;
    /**
     * Attribute from <gids-designer:cell-info> - joined-cell-count-v <p>
     * Integer / required; indicates that this cell is a member of a group of
     * joined-cell-count-v cells joined in the vertical direction
     * <p/>
     * @deprecated
     */
    @Deprecated
    private int joinedVertCellsCount;
    /**
     * Attribute from <gids-designer:cell-info> - joined-cell-index-v <p>
     * Integer / required; indicates that this cell is at the
     * joined-cell-index-v'th (ZERO-based) vertical position in the group of
     * which it is a member
     * <p/>
     * @deprecated
     */
    @Deprecated
    private int joinedVertCellsIndex;
    /**
     *
     */
    private boolean isOutlineVisible;
    /**
     * True when this cell is selected, either clicked on or when the
     * corresponding node in the explorer tree is selected.
     */
    private boolean isSelected;
    /**
     * Mapping between sides (TOP, RIGHT, BOTTOM, LEFT) and the corresponding
     * padding values.
     */
    private HashMap<Integer , Integer> paddingMap = new HashMap<>();
    /**
     * Border color when the cell is highlighted (selected).
     */
    private final Color highLightColor;
    /**
     * Border color for the outline of this cell.
     */
    private final Color outlineColor;


    /**
     * Build a basic border the size of the provided conainer, this is intended
     * to be used for an answer field.
     * <p/>
     * @param container a java.awt.Rectangle defining the position and size of
     *                  this object on the screen.
     */
    public CellBorder( Rectangle container )
    {
        this.cell = container;

        this.highLightColor = Color.ORANGE;
        this.outlineColor = Color.BLACK;

        this.setupAllBorders();
    }


    /**
     *
     * @param container a java.awt.Rectangle defining the position and size of
     *                  this object on the screen.
     * @param format    a <gids-designer:cell-format> element defining the
     *                  formatting rules for this border.
     */
    public CellBorder( Rectangle container , CellFormat format )
    {
        this( container , format , Color.ORANGE , Color.GRAY );
    }


    /**
     *
     * @param container a java.awt.Rectangle defining the position and size of
     *                  this object on the screen.
     * <p/>
     * @param format    a <gids-designer:cell-format> element defining the
     *                  formatting rules for this border.
     * <p/>
     * @param highLite  <p/>
     * @param outline
     */
    public CellBorder( Rectangle container , CellFormat format , Color highLite , Color outline )
    {
        this.cell = container;

        if ( format != null )
        {
            this.setupBorders( format );
            this.setupPadding( format );
        }

        this.highLightColor = highLite;
        this.outlineColor = outline;
    }


    /**
     * Create a new border for a cell which is located at topLeftX, topLeftY
     * coordinates, with the provided width and height, and with borders only on
     * the sides determined by the cell position within a set.
     * <p/>
     * @param topLeftX              top left X coordinate
     * @param topLeftY              top left Y coordinate
     * @param width                 width of this cell
     * @param height                height of this cell
     * @param joinedHorizCellsCount number of horizontally joined cells
     * @param joinedHorizCellsIndex position among the horizontal cells
     * @param joinedVertCellsCount  number of vertically joined cells
     * @param joinedVertCellsIndex  position among the vertical cells
     * <p/>
     * @deprecated
     */
    @Deprecated
    public CellBorder( int topLeftX , int topLeftY , int width , int height ,
            int joinedHorizCellsCount , int joinedHorizCellsIndex ,
            int joinedVertCellsCount , int joinedVertCellsIndex )
    {
        this.cell = new Rectangle( topLeftX , topLeftY , width , height );

        this.highLightColor = Color.ORANGE;
        this.outlineColor = Color.GRAY;

        this.joinedHorizCellsCount = joinedHorizCellsCount;
        this.joinedHorizCellsIndex = joinedHorizCellsIndex;
        this.joinedVertCellsCount = joinedVertCellsCount;
        this.joinedVertCellsIndex = joinedVertCellsIndex;

        this.setupBorders();
    }


    /**
     * Draws this cell border.
     * <p/>
     * @param g2d
     */
    @Override
    public void draw( Graphics2D g2d )
    {

        if ( this.isSelected )
        {
            // highlite the border
            g2d.setColor( this.highLightColor );
            //
            g2d.drawRect(
                    this.cell.x ,
                    this.cell.y ,
                    this.cell.width ,
                    this.cell.height );
            g2d.drawRect(
                    this.cell.x + 1 ,
                    this.cell.y + 1 ,
                    this.cell.width - 2 ,
                    this.cell.height - 2 );
        }
        else if ( this.isOutlineVisible )
        {
            // paint normally
            g2d.setColor( this.outlineColor );

            g2d.drawRect(
                    this.cell.x ,
                    this.cell.y ,
                    this.cell.width ,
                    this.cell.height );

        }

        // draw all the borders.
        for ( Integer side : this.borders.keySet() )
        {
            this.borders.get( side ).draw( g2d );
        }
    }


    /**
     * Calculates the size and position of the inner container for this cell.
     * <p/>
     * If the cell has no borders or padding, then the inner container will be
     * the same size as the cell itself.
     * <p/>
     * The inner container is necessary to calculate size and position for the
     * objects inside the cell.
     * <p/>
     * @return a java.awt.Rectangle outlining the size and position of the
     *         usable area inside this cell.
     */
    public Rectangle getInnerContainer()
    {
        int x = this.cell.x;
        int y = this.cell.y;
        int width = this.cell.width;
        int height = this.cell.height;

        Border border;
        Integer padding;

        // TOP border and padding
        border = this.borders.get( Border.TOP );
        if ( null != border )
        {
            /*
             * shift top-left corner down by the height of the top border.
             */
            y = y + border.container.height;
            /*
             * decrease the height by the height of the top border
             */
            height = height - border.container.height;
        }
        padding = this.paddingMap.get( Border.TOP );
        if ( null != padding )
        {
            /*
             * shift top-left corner down by the height of the top padding.
             */
            y = y + padding;
            /*
             * decrease the height by the height of the top padding
             */
            height = height - padding;
        }

        // RIGHT border and padding
        border = this.borders.get( Border.RIGHT );
        if ( null != border )
        {
            /*
             * decrease the container width by the width of the right border.
             */
            width = width - border.container.width;
        }
        padding = this.paddingMap.get( Border.RIGHT );
        if ( null != padding )
        {
            /*
             * decrease the container width by the width of the right padding.
             */
            width = width - padding;
        }

        // BOTTOM border and padding
        border = this.borders.get( Border.BOTTOM );
        if ( null != border )
        {
            height = height - border.container.height;
        }
        padding = this.paddingMap.get( Border.BOTTOM );
        if ( null != padding )
        {
            height = height - padding;
        }

        // LEFT border and padding
        border = this.borders.get( Border.LEFT );
        if ( null != border )
        {
            /*
             * shift top-left corner right by the width of the left border.
             */
            x = x + border.container.width;
            /*
             * decrease the container width by the width of the left border.
             */
            width = width - border.container.width;
        }
        padding = this.paddingMap.get( Border.LEFT );
        if ( null != padding )
        {
            /*
             * shift top-left corner right by the width of the left padding.
             */
            x = x + padding;
            /*
             * decrease the container width by the width of the left padding.
             */
            width = width - padding;
        }

        return new Rectangle( x , y , width , height );
    }


    /**
     * Get the number of Horizontally Joined cells, that this one is a part of.
     * <p/>
     * @return number of Horizontally Joined cells.
     * <p/>
     * @deprecated
     */
    @Deprecated
    public int getJoinedHorizCount()
    {
        return this.joinedHorizCellsCount;
    }


    /**
     *
     * @return <p/>
     * @deprecated
     */
    @Deprecated
    public int getJoinedHorizIndex()
    {
        return this.joinedHorizCellsIndex;
    }


    /**
     * Get the number of Vertically Joined cells, that this one is a part of.
     * <p/>
     * @return number of Vertically Joined cells.
     * <p/>
     * @deprecated
     */
    @Deprecated
    public int getJoinedVertCount()
    {
        return this.joinedVertCellsCount;
    }


    /**
     *
     * @return <p/>
     * @deprecated
     */
    @Deprecated
    public int getJoinedVertIndex()
    {
        return this.joinedVertCellsIndex;
    }


    /**
     * True if this cell is Horizontally Joined with the adjacent one(s).
     * <p/>
     */
    public boolean isJoinedHoriz()
    {
        return ( this.joinedHorizCellsCount == 1 ) ? false : true;
    }


    /**
     * True if this cell is Vertically Joined with the adjacent one(s).
     * <p/>
     */
    public boolean isJoinedVert()
    {
        return ( this.joinedVertCellsCount == 1 ) ? false : true;
    }


    /**
     * Set this element's border to be visible.
     * <p/>
     * @param visible
     */
    public void setOutlineVisible( boolean visible )
    {
        this.isOutlineVisible = visible;
    }


    /**
     *
     * @param joinedHoCellCount
     * @deprecated
     */
    @Deprecated
    public void setJoinedHorizCount( int joinedHoCellCount )
    {
        this.joinedHorizCellsCount = joinedHoCellCount;
    }


    /**
     *
     * @param joinedHoCellsIndex
     * @deprecated
     */
    @Deprecated
    public void setJoinedHorizIndex( int joinedHoCellsIndex )
    {
        this.joinedHorizCellsIndex = joinedHoCellsIndex;
    }


    /**
     *
     * @param joinedVeCellsCount
     * @deprecated
     */
    @Deprecated
    public void setJoinedVertCount( int joinedVeCellsCount )
    {
        this.joinedVertCellsCount = joinedVeCellsCount;
    }


    /**
     *
     * @param joinedVeCellsIndex
     * @deprecated
     */
    @Deprecated
    public void setJoinedVertIndex( int joinedVeCellsIndex )
    {
        this.joinedVertCellsIndex = joinedVeCellsIndex;
    }


    /**
     * Set this element as selected, which means it will be colored/drawn
     * differently from the others.
     * <p/>
     * @param selected
     */
    public void setSelected( boolean selected )
    {
        this.isSelected = selected;
    }


    /**
     *
     * @param visible
     */
    public void setVisible( boolean visible )
    {
        this.isOutlineVisible = visible;
    }


    /**
     *
     */
    private void setupAllBorders()
    {
        // initialize the set of borders, if it hasn't already been done.
        this.borders = new HashMap<>();

        String fuBorderThickness = Canvas.FU_SCALE_FACTOR + "";

        Border border;

        // BOTTOM border
        border = Border.createBorder(
                Border.BOTTOM ,
                ColorSpec.COLOR_NAME_BLACK ,
                CellBorder.BORDER_STYLE_SOLID ,
                fuBorderThickness ,
                this.cell );

        if ( null != border )
        {
            this.borders.put( Border.BOTTOM , border );
        }

        // LEFT border
        border = Border.createBorder(
                Border.LEFT ,
                ColorSpec.COLOR_NAME_BLACK ,
                CellBorder.BORDER_STYLE_SOLID ,
                fuBorderThickness ,
                this.cell );

        if ( null != border )
        {
            this.borders.put( Border.LEFT , border );
        }

        // RIGHT border
        border = Border.createBorder(
                Border.RIGHT ,
                ColorSpec.COLOR_NAME_BLACK ,
                CellBorder.BORDER_STYLE_SOLID ,
                fuBorderThickness ,
                this.cell );

        if ( null != border )
        {
            this.borders.put( Border.RIGHT , border );
        }

        // TOP border
        border = Border.createBorder(
                Border.TOP ,
                ColorSpec.COLOR_NAME_BLACK ,
                CellBorder.BORDER_STYLE_SOLID ,
                fuBorderThickness ,
                this.cell );

        if ( null != border )
        {
            this.borders.put( Border.TOP , border );
        }
    }


    /**
     *
     * @deprecated
     */
    @Deprecated
    private void setupBorders()
    {
        /*
         * All the borders are rectangles with the following constructor:
         *
         * Rectangle(Point p, Dimension d) : Constructs a new Rectangle whose
         * top-left corner is specified by the Point argument, and whose width
         * and height are specified by the Dimension argument.
         *
         */
        Rectangle border;

        /*
         * Dimension(int width, int height): Constructs a Dimension and
         * initializes it to the specified width and specified height.
         */
        Dimension horizBorder = new Dimension( this.cell.width ,
                this.borderThickness );
        Dimension vertBorder = new Dimension( this.borderThickness ,
                this.cell.height );

        Point topLeft = new Point(
                this.cell.x ,
                this.cell.y );

        Point topRight = new Point(
                this.cell.x + this.cell.width - this.borderThickness ,
                this.cell.y );

        Point bottomLeft = new Point(
                this.cell.x ,
                this.cell.y + this.cell.height - this.borderThickness );

        this.cellBorders = new ArrayList<>();

        // left and right borders.
        if ( this.joinedHorizCellsCount == 1 )
        {
            // horizontally single cell it will have both left and right borders.

            // Border segment at the left side of the cell.
            border = new Rectangle(
                    topLeft ,
                    vertBorder );
            //
            this.cellBorders.add( border );

            // Border segment at the right side of the cell.
            border = new Rectangle(
                    topRight ,
                    vertBorder );
            //
            this.cellBorders.add( border );
        }
        else
        {
            // part of a set of horizontally joined cells.
            if ( this.joinedHorizCellsIndex == 0 )
            {
                // FIRST cell of a set it has a left border but NOT a right one.
                border = new Rectangle(
                        topLeft ,
                        vertBorder );
                //
                this.cellBorders.add( border );

            }
            else if ( this.joinedHorizCellsIndex == ( this.joinedHorizCellsCount - 1 ) )
            {
                // LAST cell of a set it has a right border but NOT a left one.
                border = new Rectangle(
                        topRight ,
                        vertBorder );
                //
                this.cellBorders.add( border );
            }
            else
            {
                // MIDDLE of a set does NOT have a left OR right border.
            }
        }

        // top and bottom borders
        if ( this.joinedVertCellsCount == 1 )
        {
            // single vertical cell it will have top and bottom cells.

            /*
             * Border segment at the top of the cell.
             */
            border = new Rectangle(
                    topLeft ,
                    horizBorder );
            //
            this.cellBorders.add( border );

            /*
             * Border segment at the bottom of the cell.
             */
            border = new Rectangle(
                    bottomLeft ,
                    horizBorder );
            //
            this.cellBorders.add( border );
        }
        else
        {
            // part of a set of vertically joined cells.
            if ( this.joinedVertCellsIndex == 0 )
            {
                // TOP cell of a set: it has a TOP border but NOT a BOTTOM one.
                border = new Rectangle(
                        topLeft ,
                        horizBorder );
                //
                this.cellBorders.add( border );
            }
            else if ( this.joinedVertCellsIndex == ( this.joinedVertCellsCount - 1 ) )
            {
                // BOTTOM cell of a set: it has a BOTTOM border but NOT a TOP one.
                border = new Rectangle(
                        bottomLeft ,
                        horizBorder );
                //
                this.cellBorders.add( border );
            }
            else
            {
                // MIDDLE of a set does NOT have a top OR bottom border.
            }
        }
    }


    /**
     * Sets up the borders for this cell.
     * <p/>
     * @param format CellFormat object used to determine the border layout,
     *               color, size and style for this cell.
     * <p/>
     * @throws IllegalArgumentException if parameters are not within the
     *                                  acceptable values.
     * <p/>
     * @throws NoSuchElementException   <p/>
     * @throws NumberFormatException    if values in strings cannot be parsed as
     *                                  numbers.
     */
    private void setupBorders( CellFormat format )
            throws IllegalArgumentException ,
            NoSuchElementException ,
            NumberFormatException
    {
        // initialize the set of borders, if it hasn't already been done.
        this.borders = new HashMap<>();

        Border border;

        // BOTTOM border
        border = Border.createBorder(
                Border.BOTTOM ,
                format.getBorderBottomColor() ,
                format.getBorderBottomStyle() ,
                format.getBorderBottomWidth() ,
                this.cell );

        if ( null != border )
        {
            this.borders.put( Border.BOTTOM , border );
        }

        // LEFT border
        border = Border.createBorder(
                Border.LEFT ,
                format.getBorderLeftColor() ,
                format.getBorderLeftStyle() ,
                format.getBorderLeftWidth() ,
                this.cell );

        if ( null != border )
        {
            this.borders.put( Border.LEFT , border );
        }

        // RIGHT border
        border = Border.createBorder(
                Border.RIGHT ,
                format.getBorderRightColor() ,
                format.getBorderRightStyle() ,
                format.getBorderRightWidth() ,
                this.cell );

        if ( null != border )
        {
            this.borders.put( Border.RIGHT , border );
        }

        // TOP border
        border = Border.createBorder(
                Border.TOP ,
                format.getBorderTopColor() ,
                format.getBorderTopStyle() ,
                format.getBorderTopWidth() ,
                this.cell );

        if ( null != border )
        {
            this.borders.put( Border.TOP , border );
        }
    }


    /**
     * Sets up the padding for this cell.
     * <p/>
     * @param format
     */
    private void setupPadding( CellFormat format )
    {
        int padding;

        // BOTTOM
        padding = Canvas.parseFUSize( format.getPaddingBottom() );
        if ( padding > 0 )
        {
            this.paddingMap.put( Border.BOTTOM , padding );
        }

        // LEFT
        padding = Canvas.parseFUSize( format.getPaddingLeft() );
        if ( padding > 0 )
        {
            this.paddingMap.put( Border.LEFT , padding );
        }

        // RIGHT
        padding = Canvas.parseFUSize( format.getPaddingRight() );
        if ( padding > 0 )
        {
            this.paddingMap.put( Border.RIGHT , padding );
        }

        // TOP
        padding = Canvas.parseFUSize( format.getPaddingTop() );
        if ( padding > 0 )
        {
            this.paddingMap.put( Border.TOP , padding );
        }
    }


//    /**
//     *
//     * @param x
//     * @param y
//     */
//    @Override
//    public void moveTo( int x , int y )
//    {
//        this.cell.x = x;
//        this.cell.y = y;
//    }
    /**
     * Private class to help with the layout of the individual ( TOP , RIGHT ,
     * BOTTOM, LEFT ) borders.
     */
    private static class Border implements Drawable
    {

        /**
         * Location of the TOP border.
         */
        public final static int TOP = 0;
        /**
         * Location of the RIGHT border.
         */
        public final static int RIGHT = 1;
        /**
         * Location of the BOTTOM border.
         */
        public final static int BOTTOM = 2;
        /**
         * Location of the LEFT border.
         */
        public final static int LEFT = 3;
        /**
         * The java.awt.Color to fill this border with.
         * <p/>
         * NOTE: Color can be NULL! This is done to handle a transparent border.
         * A transparent border will have a size and occupy space on the canvas,
         * however it will not be drawn.
         */
        private Color color;
        /**
         * The java.awt.Rectangle representing the dimension and top left corner
         * point for this Border.
         */
        private Rectangle container;


        /**
         * Using a private constructor so we can use a factory function instead.
         */
        private Border()
        {
        }


        /**
         * Using a private constructor so we can use a factory function instead.
         * <p/>
         * @param r
         * @param c
         */
        private Border( Rectangle r , Color c )
        {
            this.container = r;
            this.color = c;
        }


        /**
         * Draws this border onto the canvas provided by the Graphics2D
         * parameter.
         * <p/>
         * @param g2d Graphics2D canvas on which to draw the border.
         */
        @Override
        public void draw( Graphics2D g2d )
        {
            if ( null != this.color )
            {
                g2d.setColor( this.color );
                // fillRect(int x, int y, int width, int height)
                g2d.fill( this.container );
            }
        }


        /**
         * Creates a new border object with the given parameters.
         * <p/>
         * Use this function as a Border factory instead of a regular
         * constructor so we can return a "null" object when trying to create a
         * border with zero width or height.
         * <p/>
         * @param location
         * @param colorDef
         * @param style
         * @param size
         * @param container
         * @return
         * @throws IllegalArgumentException
         * @throws NoSuchElementException
         * @throws NumberFormatException
         */
        public static Border createBorder(
                int location ,
                String colorDef ,
                String style ,
                String size ,
                Rectangle container )
                throws IllegalArgumentException ,
                NoSuchElementException ,
                NumberFormatException
        {

            Border b = null;

            int borderSize = Canvas.parseFUSize( size );

            if ( borderSize > 0 )
            {
                Color c = null;
                Rectangle r;

                if ( CellBorder.BORDER_STYLE_SOLID.equals( style ) )
                {
                    // Only work with solid borders.
                    c = ColorSpec.parseColorString( colorDef );
                }

                //
                r = Border.calcPlacement( location , borderSize , container );

                b = new Border( r , c );
            }

            //
            return b;
        }


        /**
         * Based on this Border's placement within the cell (TOP, RIGHT, BOTTOM,
         * LEFT) calculate it's location and size.
         * <p/>
         * @param location  where to place the border. Allowed values are TOP,
         *                  BOTTOM, LEFT, and RIGHT.
         * <p/>
         * @param size      of the border, will be interpreted as height or
         *                  width depending on the location.
         * <p/>
         * @param container that this border is placed inside of.
         * <p/>
         * @return a Rectangle placed according to the border's location and
         *         sized to fit inside the container.
         * <p/>
         * @throws IllegalArgumentException if the location parameter does not
         *                                  match one of the allowed values.
         */
        private static Rectangle calcPlacement( int location , int size , Rectangle container )
                throws IllegalArgumentException
        {
            Rectangle r;

            switch ( location )
            {
                case Border.BOTTOM:
                    /*
                     * The border is at the BOTTOM of the container, the origin
                     * point is shifted downwards by the HEIGHT of the container
                     * MINUS the border's HEIGHT; the border's WIDTH is the same
                     * as the container's, and the 'size' parameter indicates
                     * the border's HEIGHT.
                     */
                    int borderY = container.y + container.height - size;
                    r = new Rectangle( container.x , borderY , container.width ,
                            size );
                    break;
                case Border.LEFT:
                    /*
                     * The border is at the LEFT of the container, it has the
                     * same origin point and HEIGHT, the 'size' parameter
                     * indicates the border's WIDTH.
                     */
                    r = new Rectangle( container.x , container.y , size ,
                            container.height );
                    break;
                case Border.RIGHT:
                    /*
                     * The border is at the RIGHT of the container, the origin
                     * point is shifted right by the WIDTH of the container
                     * MINUS the border's WIDTH. The border's HEIGHT is the same
                     * as the container's, and the 'size' parameter indicates
                     * the border's WIDTH.
                     */
                    int borderX = container.x + container.width - size;
                    r = new Rectangle( borderX , container.y , size ,
                            container.height );
                    break;
                case Border.TOP:
                    /*
                     * The border is at the TOP of the container, it has the
                     * same origin point and WIDTH, the 'size' parameter
                     * indicates the border's HEIGHT.
                     */
                    r = new Rectangle( container.x , container.y ,
                            container.width , size );
                    break;
                default:
                    throw new IllegalArgumentException( "The location value "
                            + location + " is outside the allowed range." );
            }

            return r;
        }

//        /**
//         *
//         * @param x
//         * @param y
//         */
//        @Override
//        public void moveTo( int x , int y )
//        {
//            this.container.x = x;
//            this.container.y = y;
//        }
    }

}
